﻿

open System
open System.Collections.Generic
open Microsoft.FSharp.Quotations
open Microsoft.FSharp.Quotations.Patterns
open Microsoft.FSharp.Quotations.DerivedPatterns
open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicFunctions

#r @"C:\Program Files\Sho 2.0 for .NET 4\packages\Optimizer\Microsoft.Solver.Foundation.dll"
open Microsoft.SolverFoundation.Common
open Microsoft.SolverFoundation.Solvers
open Microsoft.SolverFoundation.Services


let temp =
    <@ 30 + 4 * 40 * 30 @>

let quotedProgramAsData = 
    <@
        let y = 1 + 2 * 30
        20 * y
        // code here:
        // an F# program using a subset of F# language features
    @>


// test QP
module TEST =
(* minimize x^2 + y^2 + 3xy + 2x + y *)
(* notice that in the InteriorPointSolver,
   the coefficients for xy & yx should be the same (so only set ONCE!)
   if we set both 3xy and 0yx, the solver takes the later coef.
*)
    let solver = new InteriorPointSolver()
    let _, goal = solver.AddRow("dual objective value")
    solver.AddGoal(goal, 0, true)
 
    let _, x = solver.AddVariable("x")
    let _, y = solver.AddVariable("y")
 
    solver.SetCoefficient(goal, x, Rational.op_Implicit(2))
    solver.SetCoefficient(goal, y, Rational.op_Implicit(1))
    // for terms like x-y (where x != y), set its coef for only one time!
    solver.SetCoefficient(goal, Rational.op_Implicit(3), x, y)
    //solver.SetCoefficient(goal, Rational.Zero, y, x)
    solver.SetCoefficient(goal, Rational.op_Implicit(1), x, x)
    solver.SetCoefficient(goal, Rational.op_Implicit(1), y, y)
    
    
    let param = new InteriorPointSolverParams()
    solver.Solve(param) |> ignore
 
    //solver.Result
    let objectiveValue = solver.GetValue(0).ToDouble()
 
    let x0 = solver.GetValue(1).ToDouble()
    let y0 = solver.GetValue(2).ToDouble()
    x0*x0 + y0*y0 + 3.0 * x0 * y0 + 2. * x0  + y0
    //x0*x0 + y0*y0 + 0.0 * x0 * y0 + 2. * x0  + y0

